#include "pch.h"
#include "hci.h"

#include <stdio.h>
#include <memory.h>
#include <string.h>


// OGFs
#define OGF_LINK_CONTROL          0x01
#define OGF_LINK_POLICY           0x02
#define OGF_CONTROLLER_BASEBAND   0x03
#define OGF_INFORMATIONAL_PARAMETERS 0x04
#define OGF_STATUS_PARAMETERS     0x05
#define OGF_LE_CONTROLLER 0x08
#define OGF_BTSTACK 0x3d
#define OGF_VENDOR  0x3f

#define HCI_CMD_HEADER_SIZE          3
#define HCI_CMD_PAYLOAD_SIZE       255
#define HCI_CMD_BUFFER_SIZE        (HCI_CMD_HEADER_SIZE   + HCI_CMD_PAYLOAD_SIZE)
#define packet_buffer_SIZE HCI_CMD_BUFFER_SIZE


uint8_t   packet_buffer[packet_buffer_SIZE]; // opcode (16), len(8)

/**
* compact HCI Command packet description
*/
typedef struct {
	uint16_t    opcode;
	const char *format;
} hci_cmd_t;

// calculate combined ogf/ocf value
#define OPCODE(ogf, ocf) (ocf | ogf << 10)


void get_reset_command(uint8_t **pCmd, uint16_t *size)
{
	uint16_t cmd = OPCODE(OGF_CONTROLLER_BASEBAND, 0x03);
	packet_buffer[0] = cmd & 0xff;
	packet_buffer[1] = cmd >> 8;
	packet_buffer[2] = (uint8_t)0;
	*pCmd = packet_buffer;
	*size = 3;
}

void get_scan_enable_command(uint8_t **pCmd, uint16_t *size, uint8_t value)
{
	uint16_t cmd = OPCODE(OGF_CONTROLLER_BASEBAND, 0x1A);
	packet_buffer[0] = cmd & 0xff;
	packet_buffer[1] = cmd >> 8;
	packet_buffer[2] = (uint8_t)1;
	packet_buffer[3] = value;
	*pCmd = packet_buffer;
	*size = 4;
}


void get_accept_connection_request_command(uint8_t **pCmd, uint16_t *size, uint8_t *addr, uint8_t role)
{
	uint16_t cmd = OPCODE(OGF_LINK_CONTROL, 0x09);
	packet_buffer[0] = cmd & 0xff;
	packet_buffer[1] = cmd >> 8;
	packet_buffer[2] = (uint8_t)7;
	packet_buffer[3] = addr[0];
	packet_buffer[4] = addr[1];
	packet_buffer[5] = addr[2];
	packet_buffer[6] = addr[3];
	packet_buffer[7] = addr[4];
	packet_buffer[8] = addr[5];
	packet_buffer[9] = role;
	*pCmd = packet_buffer;
	*size = 10;
}

